import { sleep } from "@/utils";
import IpcParams from "../IpcParams";
import { createAgent } from './utils';
import Axios from 'axios';
import axiosRetry from 'axios-retry';

export default class TomarketGame {
  constructor(tokenInfo) {
    this.tokenInfo = tokenInfo
    const agent = createAgent(this.tokenInfo.proxy)
    const headers = {
      "Referer": "https://mini-app.tomarket.ai/",
      "Content-Type": "application/json",
      "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_7_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
      "accept": "application/json, text/plain, */*",
      "sec-fetch-site": "same-site",
      // "accept-language": "zh-CN,zh-Hans;q=0.9",
      // "accept-encoding": "gzip, deflate, br",
      "sec-fetch-mode": "cors",
      "origin": "https://mini-app.tomarket.ai",
      "sec-fetch-dest": "empty",
    }
    this.axios = Axios.create({
      headers: headers,
      httpAgent: agent,
      httpsAgent: agent,
      timeout: 90 * 1000,
    })
    axiosRetry(this.axios, {
      retries: 3, retryDelay: (retryCount) => {
        return 2000
      }
    });
  }

  async run() {
    try {
      let webSessionUrl = this.tokenInfo.tgweb
      if (webSessionUrl.startsWith("https://") == false) {
        console.error(`${this.gameInfo.phone}  error session url ${webSessionUrl}`);
        return
      }
      webSessionUrl = decodeURIComponent(webSessionUrl)
      let session = webSessionUrl.split("#tgWebAppData=")[1]
      session = session.split("&tgWebAppVersion")[0]
      const inviteUrl = this.tokenInfo.inviteUrl
      let refId = ""
      if (inviteUrl != null) {
        refId = inviteUrl.split("startapp=")[1]
      }
      this.session = session;

      const res = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/user/login", {
        method: "post",
        data: {
          init_data: session,
          invite_code: refId,
          from: "",
          is_bot: false,
        }
      })
      const token = res.data.data.access_token;
      this.headers = {
        authorization: token,
      }

      await this.claimAirdrop();

      await this.dailyClaim()

      await this.startFarm()

      await this.refreshBalance()

      try {
        await this.playGame()
      } catch (error) {
      }

      await this.refreshBalance()

      await this.finishTask()

      await this.startSpin();

      await this.upgrade()

      await this.refreshBalance()

      this.tokenInfo.score = this.user.available_balance
      const date = (new Date()).toLocaleString()
      this.tokenInfo.gameupdate = date
      this.tokenInfo.count = (this.tokenInfo.count || 0) + 1
      console.log(date, "tomarket end", this.tokenInfo.phone, "score: ", this.tokenInfo.score)
      return new IpcParams("runTomarket", this.tokenInfo)
    } catch (error) {
      console.log((new Date()).toLocaleString(), "tomarket error", this.tokenInfo.phone)
      if (error.response) {
        console.error(error.request.path, error.response)
      } else {
        console.error(error)
      }
      return new IpcParams("runTomarket", this.tokenInfo, error)
    }
  }

  async dailyClaim() {
    try {
      await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/daily/claim", {
        method: "post",
        headers: this.headers,
        data: {
          "game_id": "fa873d13-d831-4d6f-8aee-9cff7a1d0db1"
        }
      });
    } catch (error) {
      console.error("dailyClaim", error)
    }
  }

  async startFarm() {
    try {
      const farmInfoRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/farm/info", {
        method: "post",
        headers: this.headers,
        data: {
          "game_id": "53b22103-c7ff-413d-bc63-20f6fb806a07"
        }
      });
      const farmInfoData = farmInfoRes.data.data
      const canClaim = Date.now() > (farmInfoData.end_at || 0) * 1000
      if (canClaim) {
        await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/farm/claim", {
          method: "post",
          headers: this.headers,
          data: {
            "game_id": "53b22103-c7ff-413d-bc63-20f6fb806a07"
          }
        })
        console.log("claim farm")
      }
      await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/farm/start", {
        method: "post",
        headers: this.headers,
        data: {
          "game_id": "53b22103-c7ff-413d-bc63-20f6fb806a07"
        }
      })
      console.log("start farm")
    } catch (error) {
      console.error("startFarm", error)
    }
  }

  async finishTask() {
    try {
      const taskListRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/tasks/list", {
        method: "post",
        headers: this.headers,
        data: {
          "language_code": "zh-hans",
          "init_data": this.session,
        }
      })
      const taskData = taskListRes.data.data;
      const taskList = [...taskData.standard,
      ...taskData.special || [],
      ...taskData.witch_season2 || [],
      ...taskData.invite_star_group || [],
      ...taskData.default || [],
      ...taskData.free_tomato || []];
      for (let index = 0; index < taskList.length; index++) {
        const element = taskList[index];
        // 开始任务
        if (element.status == 0) {
          const startRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/tasks/start", {
            method: "post",
            headers: this.headers,
            data: {
              "task_id": element.taskId,
              "init_data": this.session,
            }
          });
          console.log("start task", element.taskId)
        }
        // check任务
        if (element.status == 1) {
          const startRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/tasks/check", {
            method: "post",
            headers: this.headers,
            data: {
              "task_id": element.taskId,
              "init_data": this.session,
            }
          });
          console.log("check task", element.taskId)
        }
        // claim任务
        if (element.status == 2) {
          const startRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/tasks/claim", {
            method: "post",
            headers: this.headers,
            data: {
              "task_id": element.taskId,
              "init_data": this.session,
            }
          });
          console.log("claim task", element.taskId)
        }
      }
    } catch (error) {
      console.error("finishTask", error);
    }
  }

  async refreshBalance() {
    try {
      const balanceRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/user/balance", {
        method: "post",
        headers: this.headers,
      })
      this.user = balanceRes.data.data
    } catch (error) {
      console.error("refreshBalance", error)
    }
  }

  async playGame() {
    await this.refreshBalance()
    const gamePass = this.user.play_passes
    for (let index = 0; index < gamePass; index++) {
      const playRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/game/play", {
        method: "post",
        headers: this.headers,
        data: {
          "game_id": "59bcd12e-04e2-404c-a172-311a0084587d"
        }
      })
      const playDur = Math.random() * 15 + 35
      await sleep(playDur * 1000)
      const points = parseInt(Math.random() * 50) + 200
      const claimRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/game/claim", {
        method: "post",
        headers: this.headers,
        data: {
          "game_id": "59bcd12e-04e2-404c-a172-311a0084587d",
          "points": points,
        }
      })
      console.log("playGame", points)
      await sleep((Math.random() + 2) * 1000)
    }
  }

  async upgrade() {
    try {
      const rankRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/rank/data", {
        method: "post",
        headers: this.headers,
        data: {
          "language_code": "zh-hans",
          "init_data": this.session,
        }
      })
      const rankData = rankRes.data.data
      const unusedStars = rankData.unusedStars
      if (unusedStars > 0) {
        await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/rank/upgrade", {
          method: "post",
          headers: this.headers,
          data: {
            "stars": unusedStars
          }
        })
      }

    } catch (error) {
      console.error("upgrade", error)
    }
  }

  async startSpin() {
    try {
      const ticketRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/user/tickets", {
        method: "post",
        headers: this.headers,
        data: {
          "language_code": "zh-hans",
          "init_data": this.session,
        }
      })
      const ticketCount = ticketRes.data.data.ticket_spin_1 || 0
      for (let index = 0; index < ticketCount; index++) {
        const spinRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/spin/raffle", {
          method: "post",
          headers: this.headers,
          data: {
            "category": "ticket_spin_1"
          }
        });
        console.log("spin/raffle", spinRes.data.data.results)
      }
    } catch (error) {
      console.error("startSpin", error)
    }
  }

  async claimAirdrop() {
    try {
      const checkRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/token/check", {
        method: "post",
        headers: this.headers,
        data: {
          "language_code": "zh-hans",
          "init_data": this.session,
          "round": "One",
        }
      });
      const checkData = checkRes.data.data;
      if (checkData.claimed == false) {
        const claimRes = await this.axios.request("https://api-web.tomarket.ai/tomarket-game/v1/token/claim", {
          method: "post",
          headers: this.headers,
          data: {
            "round": "One"
          }
        });
        const claimData = claimRes.data.data;
        const reward = claimData.tomarketReward;
        console.log("claimAirdrop", reward)
      }
      console.log("claimAirdrop", checkData.tomaAirDrop);
      this.tokenInfo.airdrop = checkData.tomaAirDrop.amount;
    } catch (error) {
      console.error(error)
    }
  }
}
